home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / xlib / toverlay.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  10.9 KB  |  463 lines

  1. /*
  2.  * Copyright 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18. ** % cc -o toverlay toverlay.c -lGL
  19. */
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <GL/gl.h>
  24. #include <GL/glx.h>
  25. #include <X11/Xlib.h>
  26. #include <X11/keysym.h>
  27.  
  28. #define DISPLAY_BOTH        0
  29. #define DISPLAY_NORMAL        1
  30. #define DISPLAY_OVERLAY        2
  31.  
  32. static void
  33. drawSquare(float c)
  34. {
  35.     glIndexf(c);
  36.  
  37.     glBegin(GL_QUADS);
  38.     glVertex3f(0.0, 0.0, 0.0);
  39.     glVertex3f(1.0, 0.0, 0.0);
  40.     glVertex3f(1.0, 1.0, 0.0);
  41.     glVertex3f(0.0, 1.0, 0.0);
  42.     glEnd();
  43. }
  44.  
  45. static void
  46. drawCheck(float c1, float c2)
  47. {
  48.     int w = 4, h = 4;
  49.     int i, j;
  50.  
  51.     for (j=0; j<h; ++j) {
  52.     for (i=0; i<w; ++i) {
  53.         glPushMatrix();
  54.         glTranslatef((1.0/w) * i, (1.0/h) * j, 0.0);
  55.         glScalef(1.0/w, 1.0/h, 1.0);
  56.         if ((i & 1) ^ (j & 1)) {
  57.         drawSquare(c1);
  58.         } else {
  59.         drawSquare(c2);
  60.         }
  61.         glPopMatrix();
  62.     }
  63.     }
  64. }
  65.  
  66. static void
  67. usage(int argc, char **argv)
  68. {
  69.     fprintf(stderr, "\n");
  70.     fprintf(stderr, "usage: %s [options]\n", argv[0]);
  71.     fprintf(stderr, "\n");
  72.     fprintf(stderr, "    OpenGL overlay plane rendering test\n");
  73.     fprintf(stderr, "\n");
  74.     fprintf(stderr, "  Options:\n");
  75.     fprintf(stderr, "    -nm       just display normal plane window\n");
  76.     fprintf(stderr, "    -ov       just display overlay plane window\n");
  77.     fprintf(stderr, "    -m mode   display both windows according to mode:\n");
  78.     fprintf(stderr, "               0  overlay is child of normal (default)\n");
  79.     fprintf(stderr, "               1  both are children of root\n");
  80.     fprintf(stderr, "               2  both are children of a child of root\n");
  81.     fprintf(stderr, "    -bindov   bind opengl to overlay window first\n");
  82.     fprintf(stderr, "    -gl       toggle opengl rendering\n");
  83.     fprintf(stderr, "    -a        toggle animation\n");
  84.     fprintf(stderr, "\n");
  85. }
  86.  
  87. static Colormap
  88. buildColormap(Display *dpy, Window win, XVisualInfo *xvis)
  89. {
  90.     Colormap cmap;
  91.  
  92.     if ((cmap = XCreateColormap(dpy, win, xvis->visual, AllocNone)) == None) {
  93.     fprintf(stderr, "can't create colormap\n");
  94.     exit(EXIT_FAILURE);
  95.     }
  96.  
  97.     if (xvis->class == PseudoColor) {
  98.     int mapSize = 1 << xvis->depth;
  99.     int firstEntry = 0;
  100.     int entry;
  101.     unsigned long *pixels;
  102.  
  103.     pixels = (unsigned long *) calloc(mapSize, sizeof(unsigned long));
  104.  
  105.     if (!XAllocColorCells(dpy, cmap, True, NULL, 0, pixels, mapSize))
  106.     {
  107.         if (!XAllocColorCells(dpy, cmap, True, NULL, 0, pixels, mapSize-1))
  108.         {
  109.         fprintf(stderr, "can't alloc enough colormap entries\n");
  110.         exit(EXIT_FAILURE);
  111.         }
  112.         firstEntry = 1;
  113.     }
  114.  
  115.     for (entry=firstEntry; entry<mapSize; ++entry) {
  116.         XColor xcol;
  117.         int hue = entry % 8;
  118.         short val = 0xffff;
  119.  
  120.         xcol.pixel = entry;
  121.         xcol.red   = (hue==1 || hue==5 || hue==6 || hue==7) ? val : 0;
  122.         xcol.green = (hue==2 || hue==4 || hue==6 || hue==7) ? val : 0;
  123.         xcol.blue  = (hue==3 || hue==4 || hue==5 || hue==7) ? val : 0;
  124.         xcol.flags = DoRed | DoGreen | DoBlue;
  125.  
  126.         XStoreColor(dpy, cmap, &xcol);
  127.     }
  128.  
  129.     free((void *) pixels);
  130.     }
  131.  
  132.     return cmap;
  133. }
  134.  
  135. static void
  136. windopen(Display **dpy_ret, Window *win_ret,
  137.      GLXContext *ctx_ret, int *visAttrs,
  138.      const char *name, int w, int h)
  139. {
  140.     static Display *dpy = NULL;
  141.     int scr;
  142.     Window root;
  143.     XVisualInfo *xvis;
  144.     GLXContext ctx;
  145.     XSetWindowAttributes xswa;
  146.     Colormap cmap;
  147.     Window win;
  148.     XEvent event;
  149.  
  150.     if (dpy == NULL) {
  151.     if ((dpy = XOpenDisplay(NULL)) == NULL) {
  152.         fprintf(stderr, "can't open display\n");
  153.         exit(EXIT_FAILURE);
  154.     }
  155.     }
  156.     scr = DefaultScreen(dpy);
  157.     root = RootWindow(dpy, scr);
  158.  
  159.     if ((xvis = glXChooseVisual(dpy, scr, visAttrs)) == NULL) {
  160.     fprintf(stderr, "can't find visual\n");
  161.     exit(EXIT_FAILURE);
  162.     }
  163.  
  164.     if ((ctx = glXCreateContext(dpy, xvis, NULL, True)) == None) {
  165.     fprintf(stderr, "can't create context\n");
  166.     exit(EXIT_FAILURE);
  167.     }
  168.  
  169.     xswa.colormap = buildColormap(dpy, root, xvis);
  170.     xswa.background_pixel = 0;
  171.     xswa.border_pixel = 0;
  172.     xswa.event_mask = KeyPressMask | ExposureMask | StructureNotifyMask;
  173.     win = XCreateWindow(dpy, root, 0, 0, w, h, 0,
  174.             xvis->depth, InputOutput, xvis->visual,
  175.             CWColormap | CWBackPixel | CWBorderPixel | CWEventMask,
  176.             &xswa);
  177.     
  178.     if (name) {
  179.     XStoreName(dpy, win, name);
  180.     }
  181.     
  182.     *dpy_ret = dpy;
  183.     *win_ret = win;
  184.     *ctx_ret = ctx;
  185. }
  186.  
  187. static Bool
  188. waitForNotify(Display *dpy, XEvent *event, XPointer arg)
  189. {
  190.     return (event->type == MapNotify && event->xmap.window == (Window) arg);
  191. }
  192.  
  193. static int normalVisAttrs[] = {
  194.     GLX_LEVEL, 0,
  195.     GLX_BUFFER_SIZE, 4,
  196.     None
  197. };
  198.  
  199. static int overlayVisAttrs[] = {
  200.     GLX_LEVEL, 1,
  201.     GLX_BUFFER_SIZE, 2,
  202.     None
  203. };
  204.  
  205. int
  206. main(int argc, char **argv)
  207. {
  208.     int mode = DISPLAY_BOTH;
  209.     int useGL = 1;
  210.     int animate = 1;
  211.     int manageTogether = 1;
  212.     int manageUsingParent = 0;
  213.     int delayBind = 0;
  214.     int width = 300, height = 300;
  215.     int ovWidth = width, ovHeight = height;
  216.     float spin0 = 0.0, spinRate0 = 1.0;
  217.     float spin1 = 45.0, spinRate1 = -1.0;
  218.     int normInit = 0;
  219.     int overInit = 0;
  220.     Display *dpy;
  221.     Window parentWin = None;
  222.     GLXContext parentCtx = None;
  223.     Window normWin = None;
  224.     GLXContext normCtx = None;
  225.     Window overWin = None;
  226.     GLXContext overCtx = None;
  227.     XEvent event;
  228.     int i;
  229.  
  230.     for (i=1; i<argc; ++i) {
  231.     if (!strcmp("-nm", argv[i]))
  232.     {
  233.         mode = DISPLAY_NORMAL;
  234.     }
  235.     else if (!strcmp("-ov", argv[i]))
  236.     {
  237.         mode = DISPLAY_OVERLAY;
  238.     }
  239.     else if (!strcmp("-m", argv[i]) && (i+1 < argc))
  240.     {
  241.         mode = DISPLAY_BOTH;
  242.         switch (atoi(argv[++i])) {
  243.           case 0:
  244.         manageTogether = 1; manageUsingParent = 0;
  245.         break;
  246.           case 1:
  247.         manageTogether = 0; manageUsingParent = 0;
  248.         break;
  249.           case 2:
  250.         manageTogether = 1; manageUsingParent = 1;
  251.         break;
  252.           default:
  253.         usage(argc, argv);
  254.         exit(EXIT_FAILURE);
  255.         break;
  256.         }
  257.     }
  258.     else if (!strcmp("-bindov", argv[i]))
  259.     {
  260.         delayBind = 1;
  261.     }
  262.     else if (!strcmp("-gl", argv[i]))
  263.     {
  264.         useGL = !useGL;
  265.     }
  266.     else if (!strcmp("-a", argv[i]))
  267.     {
  268.         animate = !animate;
  269.     }
  270.     else
  271.     {
  272.         usage(argc, argv);
  273.         exit(EXIT_FAILURE);
  274.     }
  275.     }
  276.  
  277.     if (mode == DISPLAY_BOTH && manageUsingParent) {
  278.     windopen(&dpy, &parentWin, &parentCtx,
  279.          normalVisAttrs, "overlay test", width, height);
  280.  
  281.     XMapWindow(dpy, parentWin);
  282.     XIfEvent(dpy, &event, waitForNotify, (XPointer) parentWin);
  283.     }
  284.  
  285.     if (mode == DISPLAY_BOTH || mode == DISPLAY_NORMAL) {
  286.     windopen(&dpy, &normWin, &normCtx,
  287.          normalVisAttrs, "overlay test", width, height);
  288.  
  289.     if (mode == DISPLAY_BOTH && manageUsingParent) {
  290.         XReparentWindow(dpy, normWin, parentWin, 0, 0);
  291.     }
  292.  
  293.     XMapWindow(dpy, normWin);
  294.     XIfEvent(dpy, &event, waitForNotify, (XPointer) normWin);
  295.  
  296.     if (useGL && !delayBind) {
  297.         glXMakeCurrent(dpy, normWin, normCtx);
  298.     }
  299.     }
  300.  
  301.     if (mode == DISPLAY_BOTH || mode == DISPLAY_OVERLAY) {
  302.     windopen(&dpy, &overWin, &overCtx,
  303.          overlayVisAttrs, "overlay test", ovWidth, ovHeight);
  304.     
  305.     if (mode == DISPLAY_BOTH && manageTogether) {
  306.         if (manageUsingParent) {
  307.         XReparentWindow(dpy, overWin, parentWin, 0, 0);
  308.         } else {
  309.         XReparentWindow(dpy, overWin, normWin, 0, 0);
  310.         }
  311.     }
  312.  
  313.     XMapWindow(dpy, overWin);
  314.     XIfEvent(dpy, &event, waitForNotify, (XPointer) overWin);
  315.  
  316.     if (useGL && !delayBind) {
  317.         glXMakeCurrent(dpy, overWin, overCtx);
  318.     }
  319.     }
  320.  
  321.     if (mode == DISPLAY_BOTH && manageTogether) {
  322.     Window winList[3];
  323.  
  324.     if (manageUsingParent) {
  325.         winList[0] = overWin;
  326.         winList[1] = normWin;
  327.         winList[2] = parentWin;
  328.         XSetWMColormapWindows(dpy, parentWin, winList, 3);
  329.     } else {
  330.         winList[0] = overWin;
  331.         winList[1] = normWin;
  332.         XSetWMColormapWindows(dpy, normWin, winList, 2);
  333.     }
  334.     }
  335.  
  336.     while (1) {
  337.     int reconfigure = 0;
  338.     int redraw = 0;
  339.  
  340.     if (XPending(dpy)) {
  341.         KeySym ks;
  342.  
  343.         XNextEvent(dpy, &event);
  344.         switch (event.type) {
  345.           case KeyPress:
  346.         XLookupString(&event.xkey, NULL, 0, &ks, NULL);
  347.         if (ks == XK_Escape) {
  348.             exit(EXIT_SUCCESS);
  349.         }
  350.         break;
  351.           case Expose:
  352.         redraw = 1;
  353.         break;
  354.           case ConfigureNotify:
  355.         if (mode == DISPLAY_BOTH && manageTogether) {
  356.             if (manageUsingParent &&
  357.             event.xconfigure.window == parentWin)
  358.             {
  359.             width = ovWidth = event.xconfigure.width;
  360.             height = ovHeight = event.xconfigure.height;
  361.             XResizeWindow(dpy, normWin, width, height);
  362.             XResizeWindow(dpy, overWin, ovWidth, ovHeight);
  363.             }
  364.             if (!manageUsingParent &&
  365.             event.xconfigure.window == normWin)
  366.             {
  367.             width = ovWidth = event.xconfigure.width;
  368.             height = ovHeight = event.xconfigure.height;
  369.             XResizeWindow(dpy, overWin, ovWidth, ovHeight);
  370.             }
  371.         } else {
  372.             if (event.xconfigure.window == normWin) {
  373.             width = event.xconfigure.width;
  374.             height = event.xconfigure.height;
  375.             }
  376.             if (event.xconfigure.window == overWin) {
  377.             ovWidth = event.xconfigure.width;
  378.             ovHeight = event.xconfigure.height;
  379.             }
  380.         }
  381.         reconfigure = 1;
  382.         redraw = 1;
  383.         break;
  384.           default:
  385.         break;
  386.         }
  387.     }
  388.  
  389.     if (animate) {
  390.         spin0 += spinRate0;
  391.         if (spin0 > 360.0) spin0 -= 360.0;
  392.  
  393.         spin1 += spinRate1;
  394.         if (spin1 > 360.0) spin1 -= 360.0;
  395.  
  396.         redraw = 1;
  397.     }
  398.  
  399.     if (useGL) {
  400.         if (mode == DISPLAY_BOTH || mode == DISPLAY_OVERLAY) {
  401.         if (mode == DISPLAY_BOTH || !overInit) {
  402.             glXMakeCurrent(dpy, overWin, overCtx);
  403.  
  404.             if (!overInit) {
  405.             glMatrixMode(GL_PROJECTION);
  406.             glOrtho(-1, 1, -1, 1, 1, 3);
  407.             glMatrixMode(GL_MODELVIEW);
  408.             glTranslatef(0.0, 0.0, -2.0);
  409.             glLineWidth(4.0);
  410.             overInit = 1;
  411.             }
  412.         }
  413.  
  414.         if (reconfigure) {
  415.             glViewport(0, 0, ovWidth, ovHeight);
  416.         }
  417.  
  418.         if (redraw) {
  419.             glClear(GL_COLOR_BUFFER_BIT);
  420.  
  421.             glPushMatrix();
  422.             glRotatef(spin1, 0, 0, 1);
  423.             glScalef(1.25, 1.25, 1.0);
  424.             glTranslatef(-0.5, -0.5, 0.0);
  425.             glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  426.             drawCheck(1, 2);
  427.             glPopMatrix();
  428.         }
  429.         }
  430.  
  431.         if (mode == DISPLAY_BOTH || mode == DISPLAY_NORMAL) {
  432.         if (mode == DISPLAY_BOTH || !normInit) {
  433.             glXMakeCurrent(dpy, normWin, normCtx);
  434.  
  435.             if (!normInit) {
  436.             glMatrixMode(GL_PROJECTION);
  437.             glOrtho(-1, 1, -1, 1, 1, 3);
  438.             glMatrixMode(GL_MODELVIEW);
  439.             glTranslatef(0.0, 0.0, -2.0);
  440.             normInit = 1;
  441.             }
  442.         }
  443.  
  444.         if (reconfigure) {
  445.             glViewport(0, 0, width, height);
  446.         }
  447.  
  448.         if (redraw) {
  449.             glClear(GL_COLOR_BUFFER_BIT);
  450.  
  451.             glPushMatrix();
  452.             glRotatef(spin0, 0, 0, 1);
  453.             glScalef(1.25, 1.25, 1.0);
  454.             glTranslatef(-0.5, -0.5, 0.0);
  455.             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  456.             drawCheck(3, 4);
  457.             glPopMatrix();
  458.         }
  459.         }
  460.     }
  461.     }
  462. }
  463.